package com.lh.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lh.entity.table.FileDirectory;
import com.lh.entity.table.FileInfo;
import com.lh.entity.table.FileProperties;
import com.lh.entity.vo.UploadResponse;
import com.lh.mapper.FileDirectoryMapper;
import com.lh.mapper.FileInfoMapper;
import com.lh.utils.Answer;
import com.lh.utils.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@RestController
@RequestMapping("/fileData")
public class FileDataController {

    private LogUtil LOG = new LogUtil(FileDataController.class);


    @Autowired
    private FileDirectoryMapper fileDirectoryMapper;

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private FileProperties fileProperties;
    /**
     * 单文件上传
     * @param file 上传的文件
     * @return 上传结果
     */
    @PostMapping("/upload")
    public ResponseEntity<UploadResponse> uploadFile(
            @RequestParam("file") MultipartFile file) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body(new UploadResponse("文件为空，请选择文件上传"));
        }
        try {
            // 创建上传目录（如果不存在）
            Path uploadPath = Paths.get(fileProperties.getUploadPath());
//            Path uploadPath = Paths.get("./uploads");
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 生成唯一文件名，防止覆盖
            String originalFileName = file.getOriginalFilename();
            String fileExtension = "";
            if (originalFileName != null && originalFileName.contains(".")) {
                fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
            }
            String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
            // 保存文件到服务器
            Path filePath = uploadPath.resolve(uniqueFileName);
            Files.copy(file.getInputStream(), filePath);
            String fileUrl = fileProperties.getOutPath() + "uploads/" + uniqueFileName;
            // 返回成功响应
            UploadResponse response = new UploadResponse(
                    "文件上传成功",
                    200,
                    originalFileName,
                    uniqueFileName,
                    fileUrl,
                    file.getSize()
            );
            return ResponseEntity.ok(response);

        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new UploadResponse("文件上传失败: " + e.getMessage()));
        }
    }


    @RequestMapping("/addFileDirectory")
    public Answer<Object> addLearnInfo(@RequestBody FileDirectory fileDirectory) {
        try{
            String directoryName = fileDirectory.getDirectoryName();
            if(StrUtil.isBlank(directoryName)){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "目录名称不能为空");
            }
            FileDirectory oldFileDirectory = fileDirectoryMapper.selectOne(Wrappers.<FileDirectory>lambdaQuery().eq(FileDirectory::getDirectoryName, directoryName));
            if(oldFileDirectory != null){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "目录已存在");
            }
            fileDirectoryMapper.insert(fileDirectory);
            return Answer.ok("请求成功");
        }catch (Exception e){
            e.printStackTrace();
            return LOG.error(Answer.build(), "请求addFileDirectory失败！", e);
        }
    }

    @RequestMapping("/getFileDirectory")
    public Answer<Object> getFileDirectory(@RequestBody FileDirectory fileDirectory) {
        try{
            BigInteger id = fileDirectory.getId();
            if(id==null){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "id不能为空");
            }
            List<FileDirectory> fileDirectoryList = fileDirectoryMapper.selectList(Wrappers.<FileDirectory>lambdaQuery().eq(FileDirectory::getId, id));
            return Answer.ok(fileDirectoryList);
        }catch (Exception e){
            e.printStackTrace();
            return LOG.error(Answer.build(), "请求getFileDirectory失败！", e);
        }
    }
    @RequestMapping("/getFileDirectoryAll")
    public Answer<Object> getFileDirectoryAll(@RequestBody FileDirectory fileDirectory) {
        try {
            Integer mainId = fileDirectory.getMainId();
            if(mainId==null){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "mainId不能为空");

            }
            List<FileDirectory> fileDirectoryList = fileDirectoryMapper.selectList(Wrappers.<FileDirectory>lambdaQuery().eq(FileDirectory::getMainId, mainId));
            if(CollectionUtil.isEmpty(fileDirectoryList)){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "目录不存在");
            }

            List<FileDirectory> tree = new ArrayList<>();
            Map<String, FileDirectory> map = new HashMap<>();
            // 先将所有节点放入 map 中
            for (FileDirectory node : fileDirectoryList) {
                map.put(Convert.toStr(node.getId()), node);
            }
            // 构建树形结构
            for (FileDirectory node : fileDirectoryList) {
                String parentCode = Convert.toStr(node.getParentId());
                if (parentCode == null || !map.containsKey(parentCode)) {
                    // 根节点
                    tree.add(node);
                } else {
                    // 非根节点，添加到父节点的 children 列表中
                    FileDirectory parent = map.get(parentCode);
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(node);
                }
            }
            List<JSONObject> resList = new ArrayList<>();
            for (FileDirectory node : tree) {
                JSONObject json = convertToJsonByFileDirectory(node);
                resList.add(json);
            }
            return Answer.ok(resList);
        } catch (Exception e) {
            return LOG.error(Answer.build(), "请求getFileDirectoryAll失败！", e);

        }
    }


    @RequestMapping("/addFileInfo")
    public Answer<Object> addFileInfo(@RequestBody FileInfo addFileInfo) {
        try{
            BigInteger directoryId = addFileInfo.getDirectoryId();
            String filePath = addFileInfo.getFilePath();
            if(directoryId==null){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "目录id不能为空");

            }
            if(StrUtil.isBlank(filePath)){
                return Answer.build(HttpServletResponse.SC_BAD_REQUEST, "", "文件路径不能为空");
            }
            fileInfoMapper.insert(addFileInfo);
            return Answer.ok("请求成功");
        }catch (Exception e){
            e.printStackTrace();
            return LOG.error(Answer.build(), "请求addFileInfo失败！", e);
        }
    }

    private JSONObject convertToJsonByFileDirectory(FileDirectory node) {
        JSONObject json = new JSONObject();
        json.put("directoryId", node.getId());
        json.put("directoryName", node.getDirectoryName());
        json.put("fileInfoList", fileInfoMapper.selectList(Wrappers.<FileInfo>lambdaQuery().eq(FileInfo::getDirectoryId, node.getId())));
        List<FileDirectory> children = node.getChildren();
        if (children != null && !children.isEmpty()) {
            List<JSONObject> childrenJson = new ArrayList<>();
            for (FileDirectory child : children) {
                childrenJson.add(convertToJsonByFileDirectory(child));
            }
            json.put("childType", childrenJson);
        }
        return json;
    }
}